package com.bzkj.basicinfo.service.impl.warehouse;

import com.bzkj.basicinfo.domain.warehouse.BarRelation;
import com.bzkj.basicinfo.domain.warehouse.PdaBillsList;
import com.bzkj.basicinfo.domain.warehouse.PdaMsfxBardata;
import com.bzkj.basicinfo.domain.warehouse.PdaWarehouseBillsDetail;
import com.bzkj.basicinfo.domain.warehouse.dto.BarRelationRequest;
import com.bzkj.basicinfo.domain.warehouse.dto.BarRelationResponse;
import com.bzkj.basicinfo.domain.warehouse.dto.CodeRelationResponseDto;
import com.bzkj.basicinfo.mapper.BarRelationMapper;
import com.bzkj.basicinfo.mapper.PdaBillsListMapper;
import com.bzkj.basicinfo.mapper.PdaMsfxBardataMapper;
import com.bzkj.basicinfo.service.warehouse.IBarRelationService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.bzkj.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.annotation.Resource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 条码关系Service业务层处理
 * 
 * @author lixinyu
 * @date 2025-06-30
 */
@Service
public class BarRelationServiceImpl implements IBarRelationService {
    
    private static final Logger log = LoggerFactory.getLogger(BarRelationServiceImpl.class);

    @Resource
    private BarRelationMapper barRelationMapper;

    @Resource
    private PdaBillsListMapper pdaBillsListMapper;

    @Resource
    private PdaMsfxBardataMapper pdaMsfxBardataMapper;

    @Resource
    private RestTemplate restTemplate;

    @Value("${soapUrl}")
    private String SOAP_URL;
    private static final String SOAP_ACTION = "http://tempuri.org/GetBarRelation";
    
    @Override
    public Map<String, Object> queryCodeRelationAndSave(BarRelationRequest request) {
        Map<String, Object> result = new HashMap<>();

        try {
            log.info("开始调用码关系查询接口，追溯码: {}", request.getBarCode());

            // 1. 检查追溯码是否已存在
            boolean exists = checkBarCodeExists(request.getBarCode());
            if (exists) {
                log.info("追溯码{}已存在，返回已有数据", request.getBarCode());

                // 查询已存在的单据ID
                List<String> existingBillsIDs = getBillsIDsByBarCode(request.getBarCode());
                List<BarRelation> existingData = selectBarRelationsByBarCode(request.getBarCode());

                result.put("success", true);
                result.put("message", "追溯码已存在，返回已有数据。相关单据: " + String.join(", ", existingBillsIDs));
                result.put("billsID", existingBillsIDs.isEmpty() ? "" : existingBillsIDs.get(0));
                result.put("existingBillsIDs", existingBillsIDs);
                result.put("data", convertToBarRelationData(existingData));
                result.put("isExisting", true);
                return result;
            }

            // 2. 如果不存在，则调用SOAP接口查询
            BarRelationResponse soapResponse = queryBarRelationFromSoap(request);

            if (!soapResponse.isSuccess()) {
                result.put("success", false);
                result.put("message", "SOAP查询失败: " + soapResponse.getErrorMessage());
                return result;
            }

            if (soapResponse.getData() == null || soapResponse.getData().isEmpty()) {
                result.put("success", false);
                result.put("message", "未查询到相关数据");
                return result;
            }

            // 3. 生成单据ID并保存数据
            String billsID = generateBillsID();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String currentTime = sdf.format(new Date());

            // 保存单据主表
            saveBillsMain(billsID, currentTime, request.getBarCode());

            // 解析并保存完整的数据结构
            int totalInsertCount = saveCompleteBarRelationData(billsID, request.getBarCode(), soapResponse.getData());

            result.put("success", true);
            result.put("message", "查询成功，共获取到 " + soapResponse.getData().size() + " 条数据，成功插入 " + totalInsertCount + " 条数据");
            result.put("billsID", billsID);
            result.put("data", soapResponse.getData());
            result.put("isExisting", false);

            log.info("码关系查询成功，生成单据ID: {}", billsID);

        } catch (Exception e) {
            log.error("调用码关系查询接口异常", e);
            result.put("success", false);
            result.put("message", "调用接口异常: " + e.getMessage());
        }

        return result;
    }

    @Override
    public BarRelationResponse queryBarRelationFromSoap(BarRelationRequest request) {
        BarRelationResponse response = new BarRelationResponse();
        
        try {
            log.info("开始调用SOAP接口查询条码关系，追溯码: {}", request.getBarCode());
            
            // 构建SOAP请求体
            String soapBody = buildSoapRequest(request);
            log.info("SOAP请求体: {}", soapBody);
            
            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.TEXT_XML);
            headers.set("SOAPAction", SOAP_ACTION);
            
            HttpEntity<String> entity = new HttpEntity<>(soapBody, headers);
            
            // 发送请求
            ResponseEntity<String> soapResponse = restTemplate.postForEntity(SOAP_URL, entity, String.class);
            
            log.info("SOAP响应状态: {}", soapResponse.getStatusCode());
            log.info("SOAP响应内容: {}", soapResponse.getBody());
            
            if (soapResponse.getStatusCode() == HttpStatus.OK && StringUtils.isNotEmpty(soapResponse.getBody())) {
                // 解析SOAP响应
                List<BarRelationResponse.BarRelationData> dataList = parseSoapResponse(soapResponse.getBody());
                response.setSuccess(true);
                response.setData(dataList);
                log.info("成功解析到{}条条码关系数据", dataList.size());
            } else {
                response.setSuccess(false);
                response.setErrorMessage("SOAP接口调用失败");
                log.error("SOAP接口调用失败，状态码: {}", soapResponse.getStatusCode());
            }
            
        } catch (Exception e) {
            log.error("调用SOAP接口异常", e);
            response.setSuccess(false);
            response.setErrorMessage("调用SOAP接口异常: " + e.getMessage());
        }
        
        return response;
    }
    
    /**
     * 构建SOAP请求体
     */
    private String buildSoapRequest(BarRelationRequest request) {
        StringBuilder soap = new StringBuilder();
        soap.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        soap.append("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");
        soap.append("xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" ");
        soap.append("xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">");
        soap.append("<soap:Body>");
        soap.append("<GetBarRelation xmlns=\"http://tempuri.org/\">");
        soap.append("<BarCode>").append(request.getBarCode()).append("</BarCode>");
        soap.append("<RefEntId>").append(request.getEntId()).append("</RefEntId>");
        soap.append("<RefEntIdDetail>").append(request.getRefEntId()).append("</RefEntIdDetail>");
        soap.append("</GetBarRelation>");
        soap.append("</soap:Body>");
        soap.append("</soap:Envelope>");
        
        return soap.toString();
    }
    
    /**
     * 解析SOAP响应
     */
    private List<BarRelationResponse.BarRelationData> parseSoapResponse(String soapResponse) {
        List<BarRelationResponse.BarRelationData> dataList = new ArrayList<>();

        try {
            // 从SOAP响应中提取JSON字符串
            String jsonString = extractJsonFromSoapResponse(soapResponse);
            if (StringUtils.isEmpty(jsonString)) {
                log.error("从SOAP响应中提取JSON失败");
                return dataList;
            }

            log.info("提取的JSON字符串: {}", jsonString);

            // 解析JSON为CodeRelationResponseDto
            ObjectMapper objectMapper = new ObjectMapper();
            CodeRelationResponseDto responseDto = objectMapper.readValue(jsonString, CodeRelationResponseDto.class);

            if (responseDto == null ||
                responseDto.getAlibaba_alihealth_drug_code_kyt_wes_querycoderelation_response() == null ||
                responseDto.getAlibaba_alihealth_drug_code_kyt_wes_querycoderelation_response().getResult() == null ||
                responseDto.getAlibaba_alihealth_drug_code_kyt_wes_querycoderelation_response().getResult().getModel_list() == null ||
                responseDto.getAlibaba_alihealth_drug_code_kyt_wes_querycoderelation_response().getResult().getModel_list().getCode_relation_dto() == null) {
                log.warn("JSON响应结构不完整");
                return dataList;
            }

            // 转换为BarRelationData格式
            List<CodeRelationResponseDto.CodeRelationDto> codeRelationList =
                responseDto.getAlibaba_alihealth_drug_code_kyt_wes_querycoderelation_response()
                    .getResult().getModel_list().getCode_relation_dto();

            for (CodeRelationResponseDto.CodeRelationDto codeRelationDto : codeRelationList) {
                if (codeRelationDto.getCode_relation_list() != null &&
                    codeRelationDto.getCode_relation_list().getCode_info() != null) {

                    // 处理每个code_info
                    for (CodeRelationResponseDto.CodeInfo codeInfo : codeRelationDto.getCode_relation_list().getCode_info()) {
                        BarRelationResponse.BarRelationData data = new BarRelationResponse.BarRelationData();
                        data.setCurCode(codeInfo.getCode());
                        data.setCodeLevel(codeInfo.getCode_pack_level());
                        data.setParentCode(codeInfo.getParent_code());
                        data.setCodeState(codeInfo.getStatus());

                        // 设置扫描时间为active_date
                        String scanTime = null;
                        if (codeRelationDto.getCode_active_info_d_t_o() != null &&
                            StringUtils.isNotEmpty(codeRelationDto.getCode_active_info_d_t_o().getActive_date())) {
                            scanTime = codeRelationDto.getCode_active_info_d_t_o().getActive_date();
                        } else {
                            // 如果没有active_date，使用当前时间
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            scanTime = sdf.format(new Date());
                        }
                        data.setScanTime(scanTime);

                        // 设置备注信息和其他详细信息
                        if (codeRelationDto.getBase_infos_d_t_o() != null &&
                            codeRelationDto.getBase_infos_d_t_o().getBase_info_list() != null &&
                            codeRelationDto.getBase_infos_d_t_o().getBase_info_list().getBase_info_dto() != null &&
                            !codeRelationDto.getBase_infos_d_t_o().getBase_info_list().getBase_info_dto().isEmpty()) {

                            CodeRelationResponseDto.BaseInfoDto baseInfo =
                                codeRelationDto.getBase_infos_d_t_o().getBase_info_list().getBase_info_dto().get(0);

                            CodeRelationResponseDto.ProduceInfoDto produceInfo = codeRelationDto.getProduce_info_list().getProduce_info_dto().get(0);

                            // 构建完整的备注信息，包含药品详细信息
                            String remarkBuilder = baseInfo.getPhysic_name() + " " +
                                    baseInfo.getPkg_spec() + " " +
                                    "批号:" + baseInfo.getProduce_batch_no() + " " +
                                    "生产日期:" + baseInfo.getProduce_date() + " " +
                                    "有效期:" + baseInfo.getExprie_date() + " " +
                                    "国字号:" + baseInfo.getApprove_no() + " " +
                                    "药品代码:" + baseInfo.getProduct_code() + " " +
                                    "确认数量:" + produceInfo.getPkg_amount();

                            data.setRemark(remarkBuilder);
                        }

                        dataList.add(data);
                    }
                }
            }

            log.info("成功解析到{}条条码关系数据", dataList.size());

        } catch (Exception e) {
            log.error("解析SOAP响应异常", e);
        }

        return dataList;
    }

    
    @Override
    public List<BarRelation> selectBarRelationsByBarCode(String barCode) {
        try {
            log.info("查询追溯码{}的条码关系", barCode);
            return barRelationMapper.selectBarRelationsByBarCode(barCode);
        } catch (Exception e) {
            log.error("查询条码关系异常", e);
            return new ArrayList<>();
        }
    }
    
    @Override
    public List<BarRelation> selectAllBarRelations() {
        try {
            return barRelationMapper.selectAllBarRelations();
        } catch (Exception e) {
            log.error("查询所有条码关系异常", e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<BarRelation> selectBarRelationsByCurCodes(List<String> curCodes) {
        if (curCodes == null || curCodes.isEmpty()) {
            return new ArrayList<>();
        }
        try {
            return barRelationMapper.selectBarRelationsByCurCodes(curCodes);
        } catch (Exception e) {
            log.error("根据当前码列表查询条码关系异常", e);
            return new ArrayList<>();
        }
    }
    
    @Override
    public int deleteBarRelationsByCurCodes(List<String> curCodes) {
        if (curCodes == null || curCodes.isEmpty()) {
            return 0;
        }

        try {
            log.info("开始删除{}条条码关系数据", curCodes.size());
            int result = barRelationMapper.deleteBarRelationsByCurCodes(curCodes);
            log.info("成功删除{}条条码关系数据", result);
            return result;
        } catch (Exception e) {
            log.error("删除条码关系数据异常", e);
            throw e;
        }
    }

    @Override
    public boolean checkBarCodeExists(String barCode) {
        try {
            int count = barRelationMapper.checkBarCodeExists(barCode);
            log.info("检查追溯码{}是否存在: {}", barCode, count > 0);
            return count > 0;
        } catch (Exception e) {
            log.error("检查追溯码是否存在异常", e);
            return false;
        }
    }

    @Override
    public List<String> getBillsIDsByBarCode(String barCode) {
        try {
            log.info("查询追溯码{}相关的单据ID", barCode);
            List<String> billsIDs = barRelationMapper.selectBillsIDsByBarCode(barCode);
            log.info("找到{}个相关单据", billsIDs.size());
            return billsIDs;
        } catch (Exception e) {
            log.error("查询相关单据ID异常", e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<BarRelation> selectBarRelationsByBillsID(String billsID) {
        try {
            log.info("根据单据ID{}查询条码关系", billsID);

            // 直接使用Mapper中的方法查询
            List<BarRelation> relations = barRelationMapper.selectBarRelationsByBillsID(billsID);

            log.info("单据{}查询到{}条码关系记录", billsID, relations != null ? relations.size() : 0);
            return relations != null ? relations : new ArrayList<>();

        } catch (Exception e) {
            log.error("根据单据ID查询条码关系异常", e);
            return new ArrayList<>();
        }
    }

    /**
     * 构建SOAP请求体用于码关系查询
     */
    private String buildSoapRequestForCodeRelation(BarRelationRequest request) {
        StringBuilder soapBody = new StringBuilder();
        soapBody.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        soapBody.append("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");
        soapBody.append("xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" ");
        soapBody.append("xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">");
        soapBody.append("<soap:Body>");
        soapBody.append("<GetBarRelation xmlns=\"http://tempuri.org/\">");
        soapBody.append("<EntId>").append(request.getEntId()).append("</EntId>");
        soapBody.append("<BarCode>").append(request.getBarCode()).append("</BarCode>");
        soapBody.append("<RefEntId>").append(request.getRefEntId()).append("</RefEntId>");
        soapBody.append("</GetBarRelation>");
        soapBody.append("</soap:Body>");
        soapBody.append("</soap:Envelope>");

        return soapBody.toString();
    }

    /**
     * 解析SOAP响应并转换为CodeRelationResponseDto
     */
    private CodeRelationResponseDto parseSoapToCodeRelationDto(String soapResponse, String queryBarCode) {
        try {
            // 从SOAP响应中提取JSON字符串
            String jsonString = extractJsonFromSoapResponse(soapResponse);
            if (StringUtils.isEmpty(jsonString)) {
                log.error("从SOAP响应中提取JSON失败");
                return null;
            }

            log.info("提取的JSON字符串: {}", jsonString);

            // 解析JSON为CodeRelationResponseDto
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.readValue(jsonString, CodeRelationResponseDto.class);

        } catch (Exception e) {
            log.error("解析SOAP响应异常", e);
            return null;
        }
    }

    /**
     * 从SOAP响应中提取JSON字符串
     */
    private String extractJsonFromSoapResponse(String soapResponse) {
        try {
            // 解析SOAP XML
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(new ByteArrayInputStream(soapResponse.getBytes("UTF-8")));

            // 查找GetBarRelationResult节点
            NodeList resultNodes = document.getElementsByTagName("GetBarRelationResult");
            if (resultNodes.getLength() > 0) {
                Node resultNode = resultNodes.item(0);
                String jsonString = resultNode.getTextContent();

                // 清理可能的转义字符
                jsonString = jsonString.replace("\\\"", "\"");
                if (jsonString.startsWith("\"") && jsonString.endsWith("\"")) {
                    jsonString = jsonString.substring(1, jsonString.length() - 1);
                }

                return jsonString;
            }

            log.error("未找到GetBarRelationResult节点");
            return null;

        } catch (Exception e) {
            log.error("提取JSON字符串异常", e);
            return null;
        }
    }

    /**
     * 保存码关系数据到数据库
     */
    private String saveCodeRelationData(CodeRelationResponseDto responseDto, String queryBarCode) {
        try {
            // 生成单据ID
            String billsID = generateBillsID();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String currentTime = sdf.format(new Date());

            // 获取码关系数据
            List<CodeRelationResponseDto.CodeRelationDto> codeRelationList =
                responseDto.getAlibaba_alihealth_drug_code_kyt_wes_querycoderelation_response()
                          .getResult().getModel_list().getCode_relation_dto();

            if (codeRelationList == null || codeRelationList.isEmpty()) {
                log.warn("没有码关系数据需要保存");
                return billsID;
            }

            // 保存单据主表
            saveBillsMain(billsID, currentTime, queryBarCode);

            // 处理每个码关系数据
            for (CodeRelationResponseDto.CodeRelationDto codeRelation : codeRelationList) {
                // 保存药品明细
                saveDrugDetail(billsID, codeRelation);

                // 保存二级码数据到PDA_Msfx_BarData_Local
                saveBarData(billsID, codeRelation);

                // 保存码关系数据到BarRelation
                saveBarRelation(codeRelation);
            }

            log.info("码关系数据保存完成，单据ID: {}", billsID);
            return billsID;

        } catch (Exception e) {
            log.error("保存码关系数据异常", e);
            throw new RuntimeException("保存数据失败: " + e.getMessage());
        }
    }

    /**
     * 生成单据ID
     */
    private String generateBillsID() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timestamp = sdf.format(new Date());
        return "CR" + timestamp;
    }

    /**
     * 将BarRelation转换为BarRelationData
     */
    private List<BarRelationResponse.BarRelationData> convertToBarRelationData(List<BarRelation> barRelations) {
        List<BarRelationResponse.BarRelationData> dataList = new ArrayList<>();

        for (BarRelation barRelation : barRelations) {
            BarRelationResponse.BarRelationData data = new BarRelationResponse.BarRelationData();
            data.setCurCode(barRelation.getCurCode());
            data.setCodeLevel(barRelation.getCodeLevel());
            data.setParentCode(barRelation.getParentCode());
            data.setScanTime(barRelation.getScanTime());
            data.setRemark(barRelation.getRemark());
            data.setCodeState(barRelation.getCodeState());
            dataList.add(data);
        }

        return dataList;
    }

    /**
     * 保存单据主表
     */
    private void saveBillsMain(String billsID, String currentTime, String queryBarCode) {
        PdaBillsList billsList = new PdaBillsList();
        billsList.setBillsID(billsID);
        billsList.setUserID("system"); // 系统用户
        billsList.setBillsType("SalesWareHouseOut"); // 销售出库
        billsList.setBillsCD("码关系查询");
        billsList.setBillsState("1"); // 默认状态
        billsList.setUploadState("0"); // 未上传
        billsList.setBillsCheck("1"); // 未确认
        billsList.setSenderId("system");
        billsList.setOwnerID("system");
        billsList.setRemarks1("追溯码: " + queryBarCode);
        billsList.setRemarks2("码关系查询生成");
        billsList.setBillsFlag("0");
        billsList.setCheckDate(currentTime);

        pdaBillsListMapper.insertPdaBillsList(billsList);
        log.info("保存单据主表成功，单据ID: {}", billsID);
    }

    /**
     * 保存药品明细
     */
    private void saveDrugDetail(String billsID, CodeRelationResponseDto.CodeRelationDto codeRelation) {
        if (codeRelation.getBase_infos_d_t_o() == null ||
            codeRelation.getBase_infos_d_t_o().getBase_info_list() == null ||
            codeRelation.getBase_infos_d_t_o().getBase_info_list().getBase_info_dto() == null) {
            return;
        }

        List<PdaWarehouseBillsDetail> detailList = new ArrayList<>();
        int i = 1;
        for (CodeRelationResponseDto.BaseInfoDto baseInfo :
             codeRelation.getBase_infos_d_t_o().getBase_info_list().getBase_info_dto()) {
            PdaWarehouseBillsDetail detail = new PdaWarehouseBillsDetail();
            detail.setBillsID(billsID);
            detail.setDrugID(baseInfo.getProd_id());
            detail.setDrugName(baseInfo.getPhysic_name());
            detail.setUid(String.valueOf(i));
            detail.setDrugGG(baseInfo.getPrepn_spec());
            detail.setDrugDW("盒"); // 默认单位
            detail.setDrugNum("1"); // 默认数量
            detail.setDrugCheckNum("1");
            detail.setRemarks(baseInfo.getPhysic_info());
            detail.setDrugCD(baseInfo.getRef_ent_id()); // 生产企业ID
            detail.setDrugBH(baseInfo.getProduct_code());
            detail.setDrugBatchNo(baseInfo.getProduce_batch_no());
            detail.setDrugPD(baseInfo.getProduce_date());
            detail.setDrugExp(baseInfo.getExprie_date());
            detail.setRemarks1(baseInfo.getApprove_no()); // 批准文号
            detail.setRemarks2(baseInfo.getPkg_spec()); // 包装规格
            detail.setFlag("0");
            i++;
            detailList.add(detail);

        }

        if (!detailList.isEmpty()) {
            pdaBillsListMapper.batchPdaWarehouseBillsDetail(detailList);
            log.info("保存药品明细成功，数量: {}", detailList.size());
        }
    }

    /**
     * 保存二级码数据到PDA_Msfx_BarData_Local
     */
    private void saveBarData(String billsID, CodeRelationResponseDto.CodeRelationDto codeRelation) {
        if (codeRelation.getCode_relation_list() == null ||
            codeRelation.getCode_relation_list().getCode_info() == null) {
            return;
        }

        List<PdaMsfxBardata> bardataList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String currentTime = sdf.format(new Date());

        // 获取药品名称（用于设置drugname字段）
        String drugName = "";
        String drugID = "";
        if (codeRelation.getBase_infos_d_t_o() != null &&
            codeRelation.getBase_infos_d_t_o().getBase_info_list() != null &&
            codeRelation.getBase_infos_d_t_o().getBase_info_list().getBase_info_dto() != null &&
            !codeRelation.getBase_infos_d_t_o().getBase_info_list().getBase_info_dto().isEmpty()) {

            CodeRelationResponseDto.BaseInfoDto baseInfo =
                codeRelation.getBase_infos_d_t_o().getBase_info_list().getBase_info_dto().get(0);
            drugName = baseInfo.getPhysic_name();
            drugID = baseInfo.getProd_id();
        }

        // 只保存二级码（code_pack_level = "2"）到PDA_Msfx_BarData_Local
        for (CodeRelationResponseDto.CodeInfo codeInfo : codeRelation.getCode_relation_list().getCode_info()) {
            if ("2".equals(codeInfo.getCode_pack_level())) {
                PdaMsfxBardata bardata = new PdaMsfxBardata();
                bardata.setCorporderid(billsID);
                bardata.setScantime(currentTime);
                bardata.setBarcode(codeInfo.getCode());
                bardata.setCodelevel(Integer.parseInt(codeInfo.getCode_pack_level()));
                bardata.setDrugname(drugName);
                bardata.setBarstate(mapCodeStatus(codeInfo.getStatus()));
                bardata.setOrderstate("0"); // 默认状态
                bardata.setBatchno(getBatchNoFromBaseInfo(codeRelation));
                bardata.setBarouttype("0"); // 默认出库类型
                bardata.setDrugid(drugID);

                bardataList.add(bardata);
            }
        }

        if (!bardataList.isEmpty()) {
            pdaMsfxBardataMapper.insertPdaMsfxBardataList(bardataList);
            log.info("保存二级码数据成功，数量: {}", bardataList.size());
        }
    }

    /**
     * 保存码关系数据到BarRelation
     */
    private void saveBarRelation(CodeRelationResponseDto.CodeRelationDto codeRelation) {
        if (codeRelation.getCode_relation_list() == null ||
            codeRelation.getCode_relation_list().getCode_info() == null) {
            return;
        }

        List<BarRelation> barRelationList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String currentTime = sdf.format(new Date());

        for (CodeRelationResponseDto.CodeInfo codeInfo : codeRelation.getCode_relation_list().getCode_info()) {
            BarRelation barRelation = new BarRelation();
            barRelation.setCurCode(codeInfo.getCode());
            barRelation.setCodeLevel(codeInfo.getCode_pack_level());
            barRelation.setParentCode(StringUtils.isNotEmpty(codeInfo.getParent_code()) ? codeInfo.getParent_code() : "");
            barRelation.setScanTime(currentTime);
            barRelation.setRemark("码关系查询生成");
            barRelation.setCodeState(mapCodeStatus(codeInfo.getStatus()));

            barRelationList.add(barRelation);
        }

        if (!barRelationList.isEmpty()) {
            barRelationMapper.insertBarRelations(barRelationList);
            log.info("保存码关系数据成功，数量: {}", barRelationList.size());
        }
    }

    /**
     * 映射码状态
     */
    private String mapCodeStatus(String status) {
        if ("O".equals(status)) {
            return "0"; // 正常
        } else if ("U".equals(status)) {
            return "1"; // 已使用
        } else {
            return "0"; // 默认正常
        }
    }

    /**
     * 从基本信息中获取批次号
     */
    private String getBatchNoFromBaseInfo(CodeRelationResponseDto.CodeRelationDto codeRelation) {
        if (codeRelation.getBase_infos_d_t_o() != null &&
            codeRelation.getBase_infos_d_t_o().getBase_info_list() != null &&
            codeRelation.getBase_infos_d_t_o().getBase_info_list().getBase_info_dto() != null &&
            !codeRelation.getBase_infos_d_t_o().getBase_info_list().getBase_info_dto().isEmpty()) {

            return codeRelation.getBase_infos_d_t_o().getBase_info_list().getBase_info_dto().get(0).getProduce_batch_no();
        }
        return "";
    }

    /**
     * 保存完整的条码关系数据到三个表
     */
    private int saveCompleteBarRelationData(String billsID, String inputBarCode, List<BarRelationResponse.BarRelationData> dataList) {
        int totalInsertCount = 0;

        try {
            // 1. 准备药品详情数据 (PDA_WareHouseOut_Bills_Detail) - 按药品去重
            List<PdaWarehouseBillsDetail> detailList = new ArrayList<>();
            Set<String> processedDrugIds = new HashSet<>();

            // 2. 准备二级码数据 (PDA_Msfx_BarData_Local) - 只保存二级码
            List<PdaMsfxBardata> bardataList = new ArrayList<>();

            // 3. 准备一级码关系数据 (BarRelation) - 只保存一级码
            List<BarRelation> barRelations = new ArrayList<>();

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String currentTime = sdf.format(new Date());



            // 首先确定输入码的级别
            String inputCodeLevel = "1"; // 默认为1级
            for (BarRelationResponse.BarRelationData data : dataList) {
                if (data.getCurCode().equals(inputBarCode)) {
                    inputCodeLevel = data.getCodeLevel();
                    break;
                }
            }
            log.info("检测到输入码级别: {}", inputCodeLevel);

            for (BarRelationResponse.BarRelationData data : dataList) {
                log.info("处理数据: curCode={}, codeLevel={}, parentCode={}",
                    data.getCurCode(), data.getCodeLevel(), data.getParentCode());
                // 提取确认数量
                String drugId = extractFromRemark(data.getRemark(), "药品代码:");

                // 处理药品详情 - 按药品ID去重，每个药品只保存一条明细
                if ("2".equals(data.getCodeLevel()) || "3".equals(data.getCodeLevel())) {
                    if (StringUtils.isNotEmpty(drugId) && !processedDrugIds.contains(drugId)) {
                        PdaWarehouseBillsDetail detail = createWarehouseBillsDetail(billsID, data, drugId);
                        if (detail != null) {
                            detailList.add(detail);
                            processedDrugIds.add(drugId);
                            log.info("添加药品明细: drugId={}", drugId);
                        }
                    }
                }

                // 处理PDA_Msfx_BarData_Local数据 - 只保存输入码本身
                if (data.getCurCode().equals(inputBarCode)) {
                    String drugId2 = extractFromRemark(data.getRemark(), "药品代码:");
                    PdaMsfxBardata bardata = createMsfxBardata(billsID, drugId2, data, currentTime);
                    if (bardata != null) {
                        bardataList.add(bardata);
                        log.info("添加输入码到PDA_Msfx_BarData_Local: curCode={}, level={}", data.getCurCode(), data.getCodeLevel());
                    }
                }

                // 处理BarRelation数据 - 暂时保存所有码到BarRelation表，便于调试
                BarRelation barRelation = createBarRelation(data, currentTime);
                if (barRelation != null) {
                    barRelations.add(barRelation);
                    log.info("添加{}级码到BarRelation: curCode={}, parentCode={}",
                        data.getCodeLevel(), data.getCurCode(), data.getParentCode());
                }
            }

            // 批量保存数据
            if (!detailList.isEmpty()) {
                pdaBillsListMapper.batchPdaWarehouseBillsDetail(detailList);
                totalInsertCount += detailList.size();
                log.info("成功插入{}条药品详情数据到PDA_WareHouseOut_Bills_Detail", detailList.size());
            }

            if (!bardataList.isEmpty()) {
                pdaMsfxBardataMapper.insertPdaMsfxBardataList(bardataList);
                totalInsertCount += bardataList.size();
                log.info("成功插入{}条二级码数据到PDA_Msfx_BarData_Local", bardataList.size());
            }

            if (!barRelations.isEmpty()) {
                barRelationMapper.insertBarRelations(barRelations);
                totalInsertCount += barRelations.size();
                log.info("成功插入{}条一级码关系数据到BarRelation", barRelations.size());
            }

        } catch (Exception e) {
            log.error("保存完整条码关系数据异常", e);
            throw new RuntimeException("保存数据失败: " + e.getMessage());
        }

        return totalInsertCount;
    }

    /**
     * 从码中提取药品ID
     */
    private String extractDrugIdFromCode(String code) {
        if (StringUtils.isEmpty(code) || code.length() < 7) {
            return null;
        }
        return code.substring(0, 7);
    }

    /**
     * 创建药品详情对象
     */
    private PdaWarehouseBillsDetail createWarehouseBillsDetail(String billsID, BarRelationResponse.BarRelationData data, String drugId) {
        try {
            PdaWarehouseBillsDetail detail = new PdaWarehouseBillsDetail();
            detail.setBillsID(billsID);
            detail.setDrugID(drugId);

            // 从备注中提取药品详细信息
            if (StringUtils.isNotEmpty(data.getRemark())) {
                String remark = data.getRemark();
                String[] parts = remark.split(" ");

                if (parts.length >= 1) {
                    detail.setDrugName(parts[0]); // 药品名称
                }
                if (parts.length >= 2) {
                    detail.setDrugGG(parts[1]); // 规格
                }

                // 提取批号
                String batchNo = extractFromRemark(remark, "批号:");
                if (StringUtils.isNotEmpty(batchNo)) {
                    detail.setDrugBatchNo(batchNo);
                }

                // 提取生产日期
                String produceDate = extractFromRemark(remark, "生产日期:");
                if (StringUtils.isNotEmpty(produceDate)) {
                    detail.setDrugPD(produceDate);
                }

                // 提取确认数量
                String drugNum = extractFromRemark(remark, "确认数量:");
                if (StringUtils.isNotEmpty(drugNum)) {
                    detail.setDrugNum(drugNum);
                    detail.setDrugCheckNum(drugNum);
                }

                // 提取有效期
                String expireDate = extractFromRemark(remark, "有效期:");
                if (StringUtils.isNotEmpty(expireDate)) {
                    detail.setDrugExp(expireDate);
                }
                // 提取国字号
                String remarks1 = extractFromRemark(remark, "国字号:");
                if (StringUtils.isNotEmpty(expireDate)) {
                    detail.setRemarks1(remarks1);
                }
            }

            detail.setDrugDW("盒"); // 默认单位
            detail.setDrugNum("1"); // 默认数量
            detail.setDrugCheckNum("1"); // 默认确认数量
            detail.setRemarks(data.getRemark());
            detail.setFlag("0"); // 默认标志

            return detail;
        } catch (Exception e) {
            log.error("创建药品详情对象异常", e);
            return null;
        }
    }

    /**
     * 从备注中提取指定字段的值
     */
    private String extractFromRemark(String remark, String prefix) {
        try {
            int startIndex = remark.indexOf(prefix);
            if (startIndex != -1) {
                startIndex += prefix.length();
                int endIndex = remark.indexOf(" ", startIndex);
                if (endIndex == -1) {
                    endIndex = remark.length();
                }
                return remark.substring(startIndex, endIndex).trim();
            }
        } catch (Exception e) {
            log.error("从备注中提取字段异常: {}", e.getMessage());
        }
        return "";
    }

    /**
     * 创建二级码数据对象
     */
    private PdaMsfxBardata createMsfxBardata(String billsID, String drugId, BarRelationResponse.BarRelationData data, String currentTime) {
        try {
            PdaMsfxBardata bardata = new PdaMsfxBardata();
            bardata.setCorporderid(billsID);
            bardata.setScantime(currentTime);
            bardata.setBarcode(data.getCurCode());
            bardata.setCodelevel(Integer.parseInt(data.getCodeLevel())); // 使用实际的码级别

            // 从备注中提取药品名称和批号
            if (StringUtils.isNotEmpty(data.getRemark())) {
                String remark = data.getRemark();
                String[] parts = remark.split(" ");
                if (parts.length >= 1) {
                    bardata.setDrugname(parts[0]);
                }

                // 提取批号
                String batchNo = extractFromRemark(remark, "批号:");
                if (StringUtils.isNotEmpty(batchNo)) {
                    bardata.setBatchno(batchNo);
                }
            }

            bardata.setBarstate(data.getCodeState());
            bardata.setOrderstate("0"); // 默认订单状态
            bardata.setBarouttype("0"); // 默认出库类型
            bardata.setDrugid(drugId); // 使用药品ID

            return bardata;
        } catch (Exception e) {
            log.error("创建二级码数据对象异常", e);
            return null;
        }
    }

    /**
     * 创建一级码关系对象
     */
    private BarRelation createBarRelation(BarRelationResponse.BarRelationData data, String currentTime) {
        try {
            BarRelation barRelation = new BarRelation();
            barRelation.setCurCode(data.getCurCode());
            barRelation.setCodeLevel(data.getCodeLevel());
            barRelation.setParentCode(data.getParentCode());
            barRelation.setScanTime(currentTime);
            barRelation.setRemark(data.getRemark());
            barRelation.setCodeState(data.getCodeState());

            return barRelation;
        } catch (Exception e) {
            log.error("创建一级码关系对象异常", e);
            return null;
        }
    }

    @Override
    public String detectCodeLevel(String barCode) {
        try {
            // 优先从PDA_Msfx_BarData_Local表中查找（输入码本身）
            List<PdaMsfxBardata> bardataList = pdaMsfxBardataMapper.selectBarcodesByDrugIDLike(barCode);
            for (PdaMsfxBardata bardata : bardataList) {
                if (barCode.equals(bardata.getBarcode())) {
                    log.info("从PDA_Msfx_BarData_Local表检测到码级别: {}", bardata.getCodelevel());
                    return String.valueOf(bardata.getCodelevel());
                }
            }

            // 如果在PDA_Msfx_BarData_Local表中找不到，再从BarRelation表中查找
            BarRelation codeInfo = barRelationMapper.selectCodeLevelByBarCode(barCode);
            if (codeInfo != null && StringUtils.isNotEmpty(codeInfo.getCodeLevel())) {
                log.info("从BarRelation表检测到码级别: {}", codeInfo.getCodeLevel());
                return codeInfo.getCodeLevel();
            }

            log.warn("无法检测到追溯码{}的级别", barCode);
            return "1"; // 默认返回1级
        } catch (Exception e) {
            log.error("检测码级别异常", e);
            return "1"; // 异常时默认返回1级
        }
    }

    @Override
    public List<BarRelation> selectChildCodesByInputCode(String barCode) {
        try {
            String inputCodeLevel = detectCodeLevel(barCode);
            log.info("输入码{}的级别为: {}", barCode, inputCodeLevel);

            if ("3".equals(inputCodeLevel)) {
                // 输入3级码，查询2级码（父级码）
                // 首先查询3级码的父级码信息
                List<BarRelation> level3Relations = barRelationMapper.selectParentCodesByCurCodes(Arrays.asList(barCode));
                List<String> level2Codes = level3Relations.stream()
                    .map(BarRelation::getParentCode)
                    .filter(parentCode -> StringUtils.isNotEmpty(parentCode))
                    .distinct()
                    .collect(Collectors.toList());

                if (!level2Codes.isEmpty()) {
                    // 查询2级码的完整信息
                    return barRelationMapper.selectBarRelationsByCurCodes(level2Codes);
                }
                return new ArrayList<>();
            } else if ("2".equals(inputCodeLevel)) {
                // 输入2级码，查询1级码（子级码）
                List<BarRelation> childCodes = barRelationMapper.selectDirectChildCodesByParentCode(barCode);

                // 去重处理
                Map<String, BarRelation> childCodeMap = new LinkedHashMap<>();
                for (BarRelation child : childCodes) {
                    String curCode = child.getCurCode();
                    if (!childCodeMap.containsKey(curCode)) {
                        childCodeMap.put(curCode, child);
                    }
                }

                log.info("输入2级码{}查询到{}条子码记录，去重后{}条", barCode, childCodes.size(), childCodeMap.size());
                return new ArrayList<>(childCodeMap.values());
            } else if ("1".equals(inputCodeLevel)) {
                // 输入1级码，1级码是最底层，没有子码
                log.info("输入的是1级码，没有子码可显示");
                return new ArrayList<>();
            } else {
                // 其他情况，返回空列表
                log.warn("未知的码级别: {}", inputCodeLevel);
                return new ArrayList<>();
            }
        } catch (Exception e) {
            log.error("查询子码异常", e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<BarRelation> selectDirectChildCodes(String parentCode) {
        try {
            log.info("查询父级码{}的直接子码", parentCode);
            List<BarRelation> childCodes = barRelationMapper.selectDirectChildCodesByParentCode(parentCode);
            log.info("查询到{}条子码记录（去重前）", childCodes.size());

            // 使用LinkedHashMap去重，以curCode为key，保持插入顺序
            Map<String, BarRelation> childCodeMap = new LinkedHashMap<>();

            for (BarRelation child : childCodes) {
                String curCode = child.getCurCode();
                if (!childCodeMap.containsKey(curCode)) {
                    childCodeMap.put(curCode, child);
                    log.debug("添加子码: {}, 级别: {}, 父级码: {}",
                        child.getCurCode(), child.getCodeLevel(), child.getParentCode());
                } else {
                    log.debug("子码{}已存在，跳过重复添加", curCode);
                }
            }

            List<BarRelation> result = new ArrayList<>(childCodeMap.values());
            log.info("去重后找到{}条子码记录", result.size());

            return result;
        } catch (Exception e) {
            log.error("查询直接子码异常", e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<BarRelation> selectCompleteBarRelationsByBarCode(String barCode) {
        try {
            log.info("开始查询完整的条码关系，输入码: {}", barCode);

            // 首先查询与输入码相关的单据ID
            List<String> billsIDs = getBillsIDsByBarCode(barCode);
            log.info("找到相关单据: {}", billsIDs);

            if (billsIDs.isEmpty()) {
                log.warn("未找到与追溯码{}相关的单据", barCode);
                return new ArrayList<>();
            }

            // 使用第一个单据ID查询完整的关系数据
            String billsID = billsIDs.get(0);
            return selectBarRelationsByBillsID(billsID);

        } catch (Exception e) {
            log.error("查询完整条码关系异常", e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<BarRelation> getInitialCodeDisplay(String barCode) {
        try {
            List<BarRelation> result = new ArrayList<>();

            // 从PDA_Msfx_BarData_Local表中查询输入码本身
            List<PdaMsfxBardata> bardataList = pdaMsfxBardataMapper.selectBarcodesByDrugIDLike(barCode);
            for (PdaMsfxBardata bardata : bardataList) {
                if (barCode.equals(bardata.getBarcode())) {
                    // 创建BarRelation对象
                    BarRelation inputCodeRelation = new BarRelation();
                    inputCodeRelation.setCurCode(bardata.getBarcode());
                    inputCodeRelation.setCodeLevel(String.valueOf(bardata.getCodelevel()));
                    inputCodeRelation.setParentCode("");
                    inputCodeRelation.setScanTime(bardata.getScantime());
                    inputCodeRelation.setRemark("输入码");
                    inputCodeRelation.setCodeState("0");

                    result.add(inputCodeRelation);
                    log.info("获取输入码信息: {}, 级别: {}", barCode, bardata.getCodelevel());
                    break;
                }
            }

            // 如果在PDA_Msfx_BarData_Local中找不到，尝试从BarRelation表中查找
            if (result.isEmpty()) {
                List<BarRelation> barRelations = barRelationMapper.selectBarRelationsByBarCode(barCode);
                for (BarRelation relation : barRelations) {
                    if (barCode.equals(relation.getCurCode())) {
                        result.add(relation);
                        log.info("从BarRelation表获取输入码信息: {}, 级别: {}", barCode, relation.getCodeLevel());
                        break;
                    }
                }
            }

            return result;

        } catch (Exception e) {
            log.error("获取初始码显示异常", e);
            return new ArrayList<>();
        }
    }
}
